import unittest
from unittest.mock import patch, MagicMock, mock_open
import click.testing
from tools.cmd.cut import cut
import tempfile
import os

class TestCutCommand(unittest.TestCase):
    """测试cut命令"""
    
    def setUp(self):
        self.runner = click.testing.CliRunner()
    
    def test_cut_help(self):
        """测试cut命令帮助"""
        result = self.runner.invoke(cut, ['--help'])
        self.assertEqual(result.exit_code, 0)
        self.assertIn('Generate slices from packages', result.output)
    
    @patch('tools.cmd.cut.SliceGenerator')
    def test_cut_basic_execution(self, mock_generator):
        """测试基本cut命令执行"""
        mock_instance = MagicMock()
        mock_generator.return_value = mock_instance
        
        with tempfile.TemporaryDirectory() as tmpdir:
            result = self.runner.invoke(cut, [
                '-r', '24.03-LTS',
                '-a', 'x86_64',
                '-o', tmpdir,
                'python3_standard'
            ])
            
            self.assertEqual(result.exit_code, 0)
            mock_generator.assert_called_once()
            mock_instance.generate.assert_called_once()
    
    def test_cut_missing_required_args(self):
        """测试缺少必需参数"""
        result = self.runner.invoke(cut, [
            '-r', '24.03-LTS',
            '-a', 'x86_64'
            # 缺少 -o 参数
        ])
        self.assertNotEqual(result.exit_code, 0)
    
    def test_cut_invalid_release(self):
        """测试无效的release参数"""
        with tempfile.TemporaryDirectory() as tmpdir:
            result = self.runner.invoke(cut, [
                '-r', '',  # 空release
                '-a', 'x86_64',
                '-o', tmpdir,
                'python3_standard'
            ])
            self.assertNotEqual(result.exit_code, 0)
    
    def test_cut_invalid_arch(self):
        """测试无效的arch参数"""
        with tempfile.TemporaryDirectory() as tmpdir:
            result = self.runner.invoke(cut, [
                '-r', '24.03-LTS',
                '-a', 'invalid_arch',
                '-o', tmpdir,
                'python3_standard'
            ])
            self.assertNotEqual(result.exit_code, 0)
    
    @patch('tools.cmd.cut.SliceGenerator')
    def test_cut_multiple_slices(self, mock_generator):
        """测试多个slice处理"""
        mock_instance = MagicMock()
        mock_generator.return_value = mock_instance
        
        with tempfile.TemporaryDirectory() as tmpdir:
            result = self.runner.invoke(cut, [
                '-r', '24.03-LTS',
                '-a', 'x86_64',
                '-o', tmpdir,
                'python3_standard',
                'python3_utils',
                'python3_core'
            ])
            
            self.assertEqual(result.exit_code, 0)
            # 验证处理了多个slice
            self.assertTrue(mock_instance.generate.called)
    
    @patch('tools.cmd.cut.os.path.exists')
    @patch('tools.cmd.cut.SliceGenerator')
    def test_cut_output_directory_creation(self, mock_generator, mock_exists):
        """测试输出目录创建"""
        mock_instance = MagicMock()
        mock_generator.return_value = mock_instance
        mock_exists.return_value = False
        
        with patch('tools.cmd.cut.os.makedirs') as mock_makedirs:
            with tempfile.TemporaryDirectory() as tmpdir:
                output_dir = os.path.join(tmpdir, 'new_output')
                result = self.runner.invoke(cut, [
                    '-r', '24.03-LTS',
                    '-a', 'x86_64',
                    '-o', output_dir,
                    'python3_standard'
                ])
                
                self.assertEqual(result.exit_code, 0)
                mock_makedirs.assert_called_once()